home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
text
/
tex
/
texas.lha
/
texas.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-11
|
15KB
|
497 lines
/*-----------------------------------------*\
> texas.c (c) 1992 by Jean-Pierre RIVIERE <
\*-----------------------------------------*/
/* necessite que parse.c ait ete compile
* avec ERR_MESS_WITHOUT_LETTER pas defini
*/
#include <stdio.h>
#include "parse.h"
#ifdef AMIGA
# define ERROR_CODE 5
#else
# define ERROR_CODE 5
#endif
#define OPTIONS "h t c;i;b s "
#define OPTION_AIDE 0
#define DEJATEX 1
#define COLONNES 2
#define INPUT 3
#define BYE_END 4
#define ESPACE 5
#define COLDEF 72
#define COLMIN 20
#ifndef ENGLISH
# define USAGE "USAGE : texas [-h] [-t] [-c <colonnes>] [<entree> [<sortie>]]\n"
# define AVIS "tExas (c) 1992 par Jean-Pierre RIVIERE\n"
# define REMARQUE "%% --- traduction automatique ---\n"
# define FORMAT "a4"
#define AIDE "tExas permet de traduire un texte à la norme Ansi en un" \
" source TeX, qui devra\ncependant être édité. Si vous avez un source" \
" TeX en 8 bits, l'option -t vous\npermettra de le transformer en 7" \
" bits.\nL'option -c permet de préciser la colonne de césure pour les" \
" textes d'entrée\nnon-TeX.\n" \
"L'option -i permet de préciser le texte à inclure au début et si un" \
"tiret est indiqué (\"-i -\"), de ne rien inclure du tout.\n" \
"L'option -b indique de ne pas ajouter \\bye en fin de texte.\n" \
"L'option -s enlève les espaces inutiles (très utile avec l'option -c).\n" \
"L'option -h sert a afficher ce texte d'aide."
const char ERR_OUVERTURE [] = "impossible d'ouvrir %s\n";
#else
# define USAGE "USAGE : texas [-h] [-t] [-c <columns>] [<input> [<output>]]\n"
# define AVIS "tExas (c) 1992 by Jean-Pierre RIVIERE\n"
# define REMARQUE "%% --- automatic translation ---\n"
# define FORMAT "a4"
#define AIDE "tExas allows that a text written according to the Ansi norm" \
" to be converted\ninto a TeX source which you should then edit. If you" \
" have an 8 bits TeX\nsource, the -t option will make the equivalent TeX" \
" 7 bits source out of it.\nThe caesura columnn can be precised with the" \
" -c option if the input text is\nnot already a TeX source.\n" \
"The -i option specifies with text to include at the beginning, and" \
" none if\nyou put a dash as the text name (\"-i -\").\n" \
"The -b option indicates to not add a \\bye at the end of the text.\n" \
"The -s option trashes extra-blanks (very useful with the -c option).\n" \
"The -h option brings you this help text."
const char ERR_OUVERTURE [] = "cannot open %s\n";
#endif
typedef struct {
char * commande; /* commande ou macro TeX */
char code [4]; /* code de la séquence escape */
} sequence;
#ifdef DEBUG
void prseq (sequence * seq)
/* affiche l'adresse et le contenu d'une séquence */
{
printf("sequence : ");
if (!seq) {
printf("NULL\n");
return;
}
if (seq->code[0] == '\0')
printf("~Null\n");
printf("%x : %s --> %s .\n", seq, seq->code, seq->commande);
}
#endif
extern char * ListeSpeciaux [];
extern sequence ListeSequences [];
#define usage() { \
fprintf(stderr, USAGE); \
exit(ERROR_CODE); \
}
#define traduire_special(c,sortie) \
if (c >= 0xA0) \
fprintf((sortie), ListeSpeciaux[(c) - 0xA0]); \
else \
fputc(' ', sortie)
void traduire_sequence (FILE * entree, FILE * sortie)
{
sequence * seq;
short sep;
short suite; /* utile en cas de séquences enchaînées */
char c [3];
# ifndef ENGLISH
static const char * messErreur = " escape séquence a l'indice";
# define MAUVAISE "mauvaise"
# define FAUSSE "fausse"
# define INCONNUE "inconnue"
# define NOCOLINTEX "pas de specification de colonnes autorisée en mode TeX\n"
# define COLERR "Nombre de colonnes incorrect, valeur par défaut (%d) prise\n"
# else /* ENGLISH */
static const char * messErreur = " escape sequence at offset";
# define MAUVAISE "bad"
# define FAUSSE "false"
# define INCONNUE "unknown"
# define NOCOLINTEX "no columns specification authorized in TeX mode\n"
# define COLERR "incorrect columns number, default value(%d) taken\n"
static const char * messErreur = " escape sequence at offset";
# endif /* ENGLISH */
static unsigned short imbrication; /* de sequences escapes */
if (fgetc(entree) != '[') {
fprintf(stderr, MAUVAISE "%s%d\n", messErreur, ftell(entree) - 1);
return;
}
suite = 0;
do {
if (!isdigit(c[0] = fgetc(entree))) {
fprintf(sortie, ":%c=" MAUVAISE "%s%d\n", c[0], messErreur, ftell(entree) - 1);
fprintf(stderr, "pseudo%s%d\n", messErreur, ftell(entree) - 1);
return;
}
if (isdigit(c[1] = fgetc(entree))) {
sep = fgetc(entree);
c[2] = '\0';
} else {
sep = c[1];
c[1] = '\0';
}
if (sep != ';' && sep != 'm') {
fprintf(stderr, FAUSSE "%s%d\n", messErreur, ftell(entree) - 1);
return;
}
/* gestion de la sequence de RAZ */
seq = ListeSequences;
if (*c == '0') {
while (imbrication--)
fprintf(sortie, "}");
imbrication = suite = 0;
} else {
imbrication += 1 - suite;
while (*seq->code != '\0' && strcmp(c, seq->code))
seq++;
if (!seq)
fprintf(stderr, INCONNUE "%s%d\n", messErreur, ftell(entree) - 1);
else
fprintf(sortie, "%s", seq->commande + suite);
suite = 1; /* pour sauter { au debut */
}
}while (sep == ';');
}
void traduire (FILE * entree, FILE * sortie, short maxcol, char dejatex,
char economie)
/*
dejatex : indique qu'on traite un fichier deja oriente TeX,
et par consequent on ne traduira que les que
les caracteres etendus
maxcol : colonne de début de césure possible. nul si pas de
césure automatique.
economie : vrai si les espaces inutiles au sens TeX sont à supprimer
*/
{
short col = 0; /* colonnes en cours */
unsigned char c; /* caractère lu */
c = '\n';
while (!feof(entree)) {
if (c >= 128)
traduire_special(c, sortie);
else
switch (c) {
default :
fputc(c, sortie);
col++;
break;
case '{' :
case '}' :
if (dejatex) {
fputc(c, sortie);
break;
}
/* la plupart du temps, \char`\{ est plus beau que \{ */
fprintf(sortie, "\\char`\\%c", c);
col += 8;
break;
case '<' :
case '>' :
if (dejatex)
putchar(c);
else {
printf("$%c$", c);
col += 3;
}
break;
case ' ' :
case '\t' :
if (dejatex) {
fputc(c, sortie);
break;
}
if (!maxcol || ++col <= maxcol)
fputc(' ', sortie);
else {
fputc('\n', sortie);
col = 0;
}
if (economie) {
while ((c = fgetc(entree)) == ' ' || c == '\t');
continue;
}
break;
case '\f' :
fprintf(sortie, "\n\\vfill\\eject\n\n");
col = 0;
break;
case 27 :
traduire_sequence(entree, sortie);
break;
case '#' :
case '$' :
case '%' :
case '&' :
case '\\' :
case '^' :
case '_' :
if (dejatex)
fputc(c, sortie);
else {
/* \char`\ est parfois obligatoire et toujours plus beau */
fprintf(sortie, "\\char`\\%c ", c);
col += 9;
}
break;
case '-' :
if (dejatex) {
fputc(c, sortie);
break;
}
if ((c = fgetc(entree)) != '\n') {
fputc('-', sortie);
col++;
} else {
col = 0;
while ((c = fgetc(entree)) == ' ' || c == '\t');
if (!isalpha(c) && c < 0xC0)
fprintf(sortie, "-\n");
else
fprintf(sortie, "\\-%%\n"); /* pour conserver le découpage */
}
continue;
case '\n' :
if (dejatex) {
fputc(c, sortie);
break;
}
{
short sauts = 0; /* nombre de sauts de lignes */
while ((c = fgetc(entree)) == '\n')
sauts++;
/* risque d'espaces inutiles en début de ligne */
if (economie && (c == ' ' || c == '\t'))
while ((c = fgetc(entree)) == ' ' || c == '\t');
/* s'il y a beaucoup de lignes sautées, on génère un
espace vertical supplémentaire */
switch(sauts) {
case 0 :
if (!maxcol || ++col >= maxcol) {
fputc('\n', sortie);
col = 0;
break;
}
fputc(' ', sortie);
break;
case 1 :
fputc('\n', sortie);
fputc('\n', sortie);
col = 0;
break;
case 2 :
case 3 :
fprintf(sortie, "\n\n\\smallskip\n\n");
col = 0;
break;
case 4 :
case 5 :
fprintf(sortie, "\n\n\\midskip\n\n");
col = 0;
break;
default :
fprintf(sortie, "\n\n\\bigskip\n\n");
col = 0;
break;
}
}
continue;
}
c = fgetc(entree);
}
}
void main (int narg, char * parg [])
{
FILE * entree;
FILE * sortie;
struct rapport rapport;
short colonnes;
char nopt;
char dejatex;
char economie;
fprintf(stderr, AVIS);
if ((nopt = parse(OPTIONS, narg, parg, &rapport)) < 0) {
if (rapport.erreur == OPT_UNKNOWN_OPTION) {
fprintf(stderr, USAGE);
exit (0);
}
fprintf(stderr, ParseErrMess, rapport.lettre);
fputc('\n', stderr);
exit(1);
}
if (rapport.options[OPTION_AIDE]) {
puts(AIDE);
exit(0);
}
entree =stdin;
sortie = stdout;
if (rapport.narg) {
/* attention, si le premier argument est "-", on ne fait rien */
if (rapport.parg[0][0] != '-' || rapport.parg[0][1] != '\0')
if (!(entree = (FILE *) fopen(rapport.parg[0], "r"))) {
fprintf(stderr, ERR_OUVERTURE, rapport.parg[0]);
parse_cleanup();
exit(1);
}
if (rapport.narg == 2)
if (!(sortie = (FILE *) fopen(rapport.parg[1], "w"))) {
fprintf(stderr, ERR_OUVERTURE, rapport.parg[1]);
parse_cleanup();
/* exit fermera tout seul le premier fichier ouvert */
exit(1);
}
}
dejatex = rapport.options[DEJATEX];
economie = rapport.options[ESPACE];
colonnes = 0;
if (rapport.options[COLONNES])
if (dejatex)
fprintf(stderr, NOCOLINTEX);
else
if ((colonnes = atoi(rapport.arguments[COLONNES])) <= COLMIN)
fprintf(stderr, COLERR, colonnes = COLDEF);
if (!rapport.options[INPUT])
fprintf(sortie, REMARQUE "\\input " FORMAT "\n\n");
else if (rapport.arguments[INPUT][0] == '-' && rapport.arguments[INPUT][1] == '\0')
fprintf(sortie, REMARQUE "\n");
else
fprintf(sortie, REMARQUE "\\input %s\n\n", rapport.arguments[INPUT]);
traduire(entree, sortie, colonnes, dejatex, economie);
if (!rapport.options[BYE_END])
fprintf(sortie, "\n\n\\bye\n");
/* pour la fermeture des fichiers, on fait confiance a exit() */
exit(0);
}
/* liste des macros traductions */
char * ListeSpeciaux [] = {
/* 0xa0 */ " ",
/* ¡ */ "!`",
/* ¢ */ "\\cents",
/* £ */ "\\pounds ",
/* ¤ */ "\\star ",
/* ¥ */ "\\yens ",
/* ¦ */ "$\\mid$",
/* § */ "\\S ",
/* ¨ */ "\\\"\\ ",
/* © */ "\\copyright ",
/* ª */ "$^{\\underbar{^{a}}}$",
/* « */ "$\\ll$",
/* ¬ */ "\\neg ",
/* */ "{\\bf -}",
/* ® */ "\\reserved",
/* ¯ */ "$^{-}$",
/* ° */ "$^{\\circ}$",
/* ± */ "$\\pm $",
/* ² */ "$^{2}$",
/* ³ */ "$^{3}$",
/* ´ */ "\\prime ",
/* µ */ "$\\mu $",
/* ¶ */ "$\\P $",
/* · */ "\\cdot ",
/* ¸ */ "\\c \\ ",
/* ¹ */ "$^{1}$",
/* º */ "$^{\\underbar{\\circ}}$",
/* » */ "$\\gg$",
/* ¼ */ "$^{1}/_{4}$",
/* ½ */ "$^{1}/_{2}$",
/* ¾ */ "$^{3}/_{4}$",
/* ¿ */ "?`",
/* À */ "\\`A",
/* Á */ "\\\'A",
/* Â */ "\\^A",
/* Ä */ "\\\"A",
/* Ã */ "\\~A",
/* Å */ "\\AA ",
/* Æ */ "\\AE ",
/* Ç */ "\\c C",
/* È */ "\\`E",
/* É */ "\\\'E",
/* Ê */ "\\^E",
/* Ë */ "\\\"E",
/* Ì */ "\\`\\I ",
/* Í */ "\\\'\\I ",
/* Î */ "\\^\\I ",
/* Ï */ "\\\"\\I ",
/* Ð */ "\\crossedD",
/* Ñ */ "\\~N",
/* Ò */ "\\`O",
/* Ó */ "\\\'O",
/* Ô */ "\\^O",
/* Õ */ "\\~O",
/* Ö */ "\\\"O",
/* × */ "$\\times $",
/* Ø */ "\\O ",
/* Ù */ "\\`U",
/* Ú */ "\\\'U",
/* Û */ "\\^U",
/* Ü */ "\\\"U",
/* Ý */ "\\\'Y",
/* Þ */ "$\\OEthp$",
/* ß */ "\\ss ",
/* à */ "\\`a",
/* á */ "\\\'a",
/* â */ "\\^a",
/* ä */ "\\\"a",
/* ã */ "\\~a",
/* å */ "\\aa ",
/* æ */ "\\ae ",
/* ç */ "\\c c",
/* è */ "\\`e",
/* é */ "\\\'e",
/* ê */ "\\^e",
/* ë */ "\\\"e",
/* ì */ "\\`\\i ",
/* í */ "\\\'\\i ",
/* î */ "\\^\\i ",
/* ï */ "\\\"\\i ",
/* ð */ "\\OEthd",
/* ñ */ "\\~n",
/* ò */ "\\`o",
/* ó */ "\\\'o",
/* ô */ "\\^o",
/* õ */ "\\~o",
/* ö */ "\\\"o",
/* ÷ */ "$\\div $",
/* ø */ "\\o ",
/* ù */ "\\`u",
/* ú */ "\\\'u",
/* û */ "\\^u",
/* ü */ "\\\"u",
/* ý */ "\\\'y",
/* þ */ "\\OEthpp",
/* ÿ */ "\\\"y"
};
/* traduction en deux parties des séquences escape */
sequence ListeSequences [] = {
{ "{\\bf ", '1' },
{ "{", "2\0\0\0" },
{ "{", "20\0\0" },
{ "{", "21\0\0" },
{ "{", "22\0\0" },
{ "{", "23\0\0" },
{ "{\\it ", "3\0\0\0" },
{ "{", "30\0\0" },
{ "{", "31\0\0" },
{ "{", "32\0\0" },
{ "{", "33\0\0" },
{ "\\underbar{", "4\0\0\0" },
{ "{", "7\0\0\0" },
{ NULL, 0,0,0,0 }
};